# encoding: utf-8
"""
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    created by lane.chang on '17/10/2024'
    comment: 接口参数测试
"""
from fastapi import APIRouter, Request, Body
from laner.pydantic import BaseModel
from enum import Enum
from typing import Optional
from project.core.base import UEnum, Element

from config import Config
from project.core.function import json_response
from project.lib.decorator import api_common, exec_duration
from project.lib.common import Global
from project.lib.validators import generate_validator, MinuteStr


flow_router = APIRouter(prefix='/u', tags=['user.flow'])


class QuestionType(Enum):
    """ 题目类型
    """
    time_period_picker = 'time_period_picker'
    text_picker = 'text_picker'
    invoice = 'invoice'
    confirm = 'confirm'
    success = 'success'


class ScoreRuleType(UEnum):
    """ 计分规则
    """
    NUMBER = Element('number', '个数')
    PERCENT = Element('percent', '百分比')
    SIMILARITY = Element('similarity', '相似度')
    AVERAGE = Element('average', '平均')
    RESULTS_SETTING = Element('results_setting', '根据答案设置')


class ScoreRule(BaseModel):
    """ 分数规则
    """
    total: int = Body(0, title='该题目分数')
    rule_type: ScoreRuleType.enums(fixed=Global.count(), with_blank=True) = Body(None, title='分数规则类型', description='个数(number)/百分比(percent)/相似度(similarity)/分答案设置(results_setting)')
    limit_lower: float = Body('0.0', title='最小限制', description='超过这个限制, 则直接满分')
    is_average: bool = Body(False, title='是否平均', description='再无法满分的时候, 是否需要平均给分')
    results_score: dict[str, float] = Body(None, title='根据答案给分数', description='例如: {"是": 2, "否": 1}')
    explain: str = Body('', max_length=200, title='得分规则说明')


class QtAlgorithm(UEnum):
    """ 题目算法
    """
    YEAR = Element('01', '年份')
    WEEKDAY = Element('02', '星期')
    MONTH = Element('03', '月份')
    DAY = Element('04', '日期')


class Keyword(UEnum):
    """ 关键字
    """
    ANIMAL = Element('animal', '动物')


class SimilarityType(UEnum):
    """ 相似度模型
    """
    CUBE = Element('cube', '立方体')
    CLOCK = Element('clock', '钟表')


class MealPeriod(BaseModel):
    """
    """
    start_time: generate_validator(MinuteStr, blank_enable=True) = Body('', title='开始时间', description='格式: %H:%M')
    end_time: generate_validator(MinuteStr, blank_enable=True) = Body('', title='开始时间', description='格式: %H:%M')


class Spec(BaseModel):
    """ 规格信息
    """
    title: str = Body('', title='规格名称')
    items: list[str] = Body([], title='规格可选列表')


class BusinessType(Enum):
    """ 业务类型
    """
    catering = 'catering'  # 餐饮
    shopping = 'shopping'  # 购物
    other = 'other'  # 其它


class InterQuestionItem(BaseModel):
    """ 题目项目
    """
    group_title: str = Body('', title='项目组名')
    group_image: str = Body('', title='项目组图标')
    group_image_checked: str = Body('', title='项目组图标(选中)')
    group_image_unchecked: str = Body('', title='项目组图标(取消选中)')
    group_meal_period: MealPeriod = Body({}, title='分类时间段', description='格式: %H:%M')
    title: str = Body('', title='项目名称')
    content: str = Body(None, title='项目说明')
    image: str = Body(None, title='项目图片')
    count: int = Body(None, title='项目数量')
    price: float = Body(None, title='项目单价')
    detail: list = Body(None, title='项目详情', description='例如: [{"audio": "", "image": "", "content": ""}, {"audio": "", "image": "", "content": ""}]')
    count_upper_limit: int = Body(0, title='数量上限')
    is_count: bool = Body(False, title='是否选择数量')
    is_spec: bool = Body(False, title='是否选择规格')
    spec: list[Spec] = Body('', title='规格信息')


class Dates(Enum):
    """ 可选日期
    """
    today = 'today'
    tomorrow = 'tomorrow'
    after_tomorrow = 'after_tomorrow'


class TimeSet(BaseModel):
    """ 时间设置
    """
    dates: list[Dates] = Body([], title='选择日期', description='today(今日)/tomorrow(明日)/after_tomorrow(后日)')
    meal_period: MealPeriod = Body({}, title='时间段', description='{"start_time": 07:00, "end_time": 08:00}')
    interval: int = Body(0, title='间隔', description='单位: 分钟')


class PhoneType(Enum):
    """
    """
    eleven_bit = 'eleven_bit'
    last_four_bit = 'last_four_bit'


class InvoiceType(UEnum):
    """ 发票类型
    """
    ELECTRONIC = Element('electronic', '电子发票')
    PAPER = Element('paper', '纸质发票')


class InterQuestionExtra(BaseModel):
    """ 题库扩展表
    """
    display_items: list[InterQuestionItem] = Body(None, title='展示项目列表')
    is_group: int = Body(0, title='展示项目是否分组 0: 不分组 1: 分组')
    select_mode: str = Body('single', title='选择方式', description='single(单选)/multiple(多选) 默认: single')

    name: str = Body('', title='对答主题')
    introduction: str = Body('', title='对答主题')
    business_type: BusinessType = Body('', title='业务类型')
    button_text: str = Body('', title='按钮文本')
    timeset: TimeSet = Body({}, title='时间段设置')
    phone_type: PhoneType = Body('', title='手机号类型 eleven_bit(11位)/last_four_bit(后四位)')
    title_icon: str = Body('', title='内容图标')
    invoice_types: list[InvoiceType.enums(Global.count(), with_blank=True)] = Body([], title='发票类型')


class InterQuestion(BaseModel):
    """ 题目
    """
    id: int = Body(0, title='题目id')
    score_rule: Optional[ScoreRule] = Body(..., title='题目分数设置规则')
    question_extra: InterQuestionExtra = Body(None, title='题目扩展信息')


@flow_router.post('/parameter/test', summary='接口参数测试', include_in_schema=False)
@api_common(doc_replace=(('{0}', Config.ENV_DOC_FIX),))
@exec_duration(add_return=True)
def do_flow_test(request: Request, inter_question: InterQuestion = Body(..., title='题目信息')):
    """
    **desc**: 提交服务记录

    **url**: http(s)://{0}.udicaria.com/u/parameter/test

    **method**: POST

    **params**:

    **return**:json数据结构::

        {
            code: 0(成功)/非0(失败)
            message: 成功返回success, 否则返回error信息
            data:
            exec_time: 接口后端处理时长
        }
    """
    return json_response()
